package cn.wizzer.framework.util;


import org.chain3j.crypto.Credentials;
import org.chain3j.crypto.RawTransaction;
import org.chain3j.crypto.TransactionEncoder;
import org.chain3j.crypto.WalletUtils;
import org.chain3j.protocol.Chain3j;
import org.chain3j.protocol.core.DefaultBlockParameter;
import org.chain3j.protocol.core.methods.response.McSendTransaction;
import org.chain3j.protocol.core.methods.response.McTransaction;
import org.chain3j.protocol.core.methods.response.Transaction;
import org.chain3j.protocol.http.HttpService;
import org.chain3j.utils.Numeric;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;

public class MoacUtil {
    private Chain3j m_chain3 = null;
    private Credentials m_fromPrivateKey = null;
    private String m_toPublickKey = null;
    private static final BigInteger sm_gasLimit = BigInteger.valueOf(21000);
    private static final BigInteger sm_sendValue = BigInteger.valueOf(1000000000000L);

    /**
     * @param url          接口路径
     * @param keystoreFile 密钥路径
     * @param password     密钥密码
     * @param toPublickKey 收款码
     */
    public MoacUtil(String url, String keystoreFile, String password, String toPublickKey) throws Exception {
        m_chain3 = Chain3j.build(new HttpService(url));
        m_fromPrivateKey = WalletUtils.loadCredentials(password, keystoreFile);
        m_toPublickKey = toPublickKey;
    }

    /**
     * 发送交易
     *
     * @param msg 消息内容
     * @return 返回交易Hash
     */
    public String sendTransaction(String msg) throws Exception {
        Integer netVersion = Integer.valueOf(m_chain3.netVersion().send().getNetVersion());
        BigInteger gasPrice = m_chain3.mcGasPrice().send().getGasPrice();
        //https://blog.csdn.net/sinat_34070003/article/details/79919431
        BigInteger nonce = m_chain3.mcGetTransactionCount(m_fromPrivateKey.getAddress(), DefaultBlockParameter.valueOf("pending")).send().getTransactionCount();
        RawTransaction rawTransaction = RawTransaction.createTransaction(
                nonce,
                gasPrice,
                sm_gasLimit,
                m_toPublickKey,
                sm_sendValue,
                Numeric.toHexString(msg.getBytes(StandardCharsets.UTF_8)));
        byte[] signedTX = TransactionEncoder.signTxEIP155(rawTransaction, netVersion, m_fromPrivateKey);
        String signedRawTx = Numeric.toHexString(signedTX);
        McSendTransaction mcSendTransaction = m_chain3.mcSendRawTransaction(signedRawTx).send();
        return mcSendTransaction.getTransactionHash();
    }

    /**
     * 查询交易
     *
     * @param hash 交易Hash
     * @return 返回消息内容
     */
    public String getTransactionByHash(String hash) throws Exception {
        McTransaction mcTransaction = m_chain3.mcGetTransactionByHash(hash).send();
        Transaction transaction = mcTransaction.getTransaction().get();
        byte[] input = Numeric.hexStringToByteArray(transaction.getInput());
        String result = new String(input, StandardCharsets.UTF_8);
        return result;
    }
}